﻿//
//

#include "pch.h"
#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>

using namespace cv;
using namespace std;

int main()
{
	Mat church = imread("E:\\VC_project\\figure\\chess.jpg");
	if (church.empty())
	{
		cout << "图片读取失败！" << endl;
		return -1;
	}

	//使用harris检测角点响应强度

	Mat grayChurch;
	cvtColor(church, grayChurch, COLOR_BGR2GRAY);

	Mat cornerStrength;
	cornerHarris(grayChurch, cornerStrength, 3, 3, 0.04);
	imshow("church", cornerStrength);

	//内部阈值计算，使用函数minMaxLoc
	double minStrength, maxStrength;
	minMaxLoc(cornerStrength, &minStrength, &maxStrength);

	//图像膨胀及局部极大值检测，减少角点聚集的情况
	Mat dilated, localMax;
	dilate(cornerStrength, dilated, Mat());
	compare(cornerStrength, dilated, localMax, CMP_EQ);

	//对图像进行阈值化
	Mat cornerMap, cornerTH, result;
	threshold(cornerStrength, cornerTH, 0.03*maxStrength, 255, THRESH_BINARY);
	//转为8位图像
	cornerTH.convertTo(cornerMap, CV_8U);
	cornerTH.convertTo(result, CV_8U);

	//非极大值抑制
	bitwise_and(cornerMap, localMax, cornerMap);
	bitwise_and(result, localMax, result);

	vector<Point> points; //定义Point类型容器，用于存放特征点（角点）
	for (int i = 0; i < cornerMap.rows; i++)
	{
		uchar* rowPtr = cornerMap.ptr<uchar>(i); //Mat型指针，用于访问一行的元素
		for (int j = 0; j < cornerMap.cols; j++)
		{
			//如果是特征点
			if (rowPtr[j])
				points.push_back(Point(j, i)); //从容器尾部添加元素
		}
	}

	vector<Point>::iterator it=points.begin();//使用迭代器访问容器中的元素.

	while (it != points.end())
	{
		//画圆
		circle(church, 
			*it,//圆心
			2,//半径 
			Scalar(0, 0, 255), 1);
		it++;
	}
	
	imshow("角点图", result);
	imshow("chess_Harris", church);
	//imshow("harrisChurch", grayChurch);
	waitKey();
}

